package cn.swust.designpatternlearningplatform.service.impl;

import cn.swust.designpatternlearningplatform.common.exception.CustomException;
import cn.swust.designpatternlearningplatform.dao.StudentTestDao;
import cn.swust.designpatternlearningplatform.dao.TopicDao;
import cn.swust.designpatternlearningplatform.domain.bo.AnswerBo;
import cn.swust.designpatternlearningplatform.domain.dto.TopicJudgeDto;
import cn.swust.designpatternlearningplatform.domain.entity.DailyExercise;
import cn.swust.designpatternlearningplatform.domain.entity.Topic;
import cn.swust.designpatternlearningplatform.event.TopicWrongEvent;
import cn.swust.designpatternlearningplatform.service.TopicJudgeService;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TopicJudgeServiceImpl implements TopicJudgeService {
    @Resource
    private ApplicationEventPublisher applicationEventPublisher;
    @Resource
    private TopicDao topicDao;
    @Resource
    private StudentTestDao studentTestDao;

    @Override
    public List<TopicJudgeDto> judgeTopic(String studentNumber, List<AnswerBo> topicJudgeBoList) {
        try {
            List<TopicJudgeDto> res = new ArrayList<>();
            //获取题目id
            Set<Integer> topicIds = topicJudgeBoList.stream().map(AnswerBo::getTopicId).collect(Collectors.toSet());
            //获取题目
            List<Topic> topicsByIds = topicDao.getTopicsByIds(topicIds);
            //获取题目类型
            Map<Integer, String> topicTypes = topicsByIds
                    .stream()
                    .collect(Collectors.toMap(Topic::getTopicId, Topic::getTopicType));
            //获取题目答案
            Map<Integer, String> topicsAnswers = topicsByIds
                    .stream()
                    .collect(Collectors.toMap(Topic::getTopicId, Topic::getTopicAnswer));
            List<DailyExercise> dailyExerciseList = new ArrayList<>();
            for (AnswerBo topicJudgeBo : topicJudgeBoList) {
                String ownAnswer = topicJudgeBo.getOwnAnswer();
                DailyExercise dailyExercise = new DailyExercise();
                dailyExercise.setIsRight(0);
                LocalDateTime now = LocalDateTime.now();
                //错题处理
                if (!judgeAnswer(ownAnswer, topicsAnswers.get(topicJudgeBo.getTopicId()))) {
                    dailyExercise.setIsRight(1);
                    TopicWrongEvent topicWrongEvent = TopicWrongEvent
                            .build(studentNumber, topicJudgeBo.getTopicId(), topicTypes.get(topicJudgeBo.getTopicId()), now);
                    applicationEventPublisher.publishEvent(topicWrongEvent);
                }
                //做题记录
                dailyExercise.setTopicId(topicJudgeBo.getTopicId());
                dailyExercise.setProblemTime(now);
                dailyExercise.setOwnAnswer(topicJudgeBo.getOwnAnswer());
                dailyExercise.setStudentNumber(studentNumber);
                dailyExerciseList.add(dailyExercise);
                res.add(new TopicJudgeDto(dailyExercise.getTopicId(), dailyExercise.getIsRight(), topicsAnswers.get(topicJudgeBo.getTopicId())));
            }
            //批量记录答题结果
            studentTestDao.insertDailyExerciseBatch(dailyExerciseList);
            return res;
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException("系统繁忙，请稍后再试");
        }
    }

    /**
     * 对证答案
     *
     * @param ownAnswer
     * @param correctAnswer
     * @return boolean
     * @author Tang
     * @date 2023/9/26 10:40
     **/
    private boolean judgeAnswer(String ownAnswer, String correctAnswer) {
        if (ownAnswer == null || correctAnswer == null) {
            return false;
        }
        if (ownAnswer.length() != correctAnswer.length()) {
            return false;
        }
        char[] ownAnswerCharArray = ownAnswer.toCharArray();
        Arrays.sort(ownAnswerCharArray);
        char[] correctAnswerCharArray = correctAnswer.toCharArray();
        Arrays.sort(correctAnswerCharArray);
        return Arrays.equals(ownAnswerCharArray, correctAnswerCharArray);
    }
}
